﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using Newtonsoft.Json;

namespace SnippetBox.Core.Infrastructure {
    public abstract class SettingsBase {
        private readonly string _settingsPath;

        protected SettingsBase() {
            var settingsPath = ConfigurationManager.AppSettings["SettingsPath"];
            if (settingsPath != null)
                _settingsPath = settingsPath;
            else
                _settingsPath = AppDomain.CurrentDomain.BaseDirectory + "settings.json";

            SettingsPath = _settingsPath;
        }

        public virtual void SetDefaultValues() {}

        [JsonIgnore, ScaffoldColumn(false)]
        public DateTime LastChanged { get; private set; }

        [JsonIgnore, ScaffoldColumn(false)]
        public bool IsLoaded { get; private set; }

        [JsonIgnore, ScaffoldColumn(false)]
        public string SettingsPath { get; private set; }

        public void SaveChanges() {
            var settingsSerialized = JsonConvert.SerializeObject(this, Formatting.Indented);
            File.WriteAllText(_settingsPath, settingsSerialized);
            
            LoadChanges();
            LastChanged = DateTime.Now;
        }

        public void LoadChanges() {
            if (!File.Exists(_settingsPath)) {
                SetDefaultValues();
                SaveChanges();
                return;
            }
            
            try {
                Settings newSettings = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(_settingsPath));
                
                if (newSettings == null)
                    return;

                var settingsType = newSettings.GetType();

                foreach (var settingProperty in GetType().GetProperties()) {
                    if (settingProperty.Name == "Current" || settingProperty.GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Any())
                        continue;

                    var propertyValue = settingsType.GetProperty(settingProperty.Name);
                    var value = propertyValue.GetValue(newSettings, null);
                    
                    if (value == null)
                        value = Activator.CreateInstance(propertyValue.PropertyType);

                    settingProperty.SetValue(this, value, null);
                }

                LastChanged = DateTime.Now;
                IsLoaded = true;
            }
            catch (Exception) {
                // if method fails - the AppPool crashes
            }
        }
    }
}
